﻿using GDM.Hogar.Aplicacion.IoC;
using GDM.Hogar.Aplicacion.Properties;
using GDM.Hogar.Controles.Animacion;
using GDM.Hogar.Managers;
using GDM.Hogar.Soporte;
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace GDM.Hogar.Aplicacion.Formularios
{
    public abstract class FrmBase : Form
    {
        protected const string ContraseñaPorDefecto = "Cambiame$";
        protected const int EdadMinima = 60;
        protected const int TamañoPagina = 100;
        protected readonly IContenedorIoC ContenedorIoC;
        private Animator _animador;
        private readonly Color _colorPanelError = Color.FromArgb(247, 247, 248); //Color.FromArgb(233, 86, 68);
        private readonly Color _colorPanelExito = Color.FromArgb(247, 247, 248); //Color.FromArgb(89, 163, 194); //Color.FromArgb(33, 174, 177);
        private System.ComponentModel.IContainer components;
        private Label _lblMensaje;
        private Label _lblTitulo;
        private Panel _pnlMensaje;
        private Panel _pnlSeparador;
        private Controles.ControlesPersonalizados.ImagenBoton.ImageButton _iBtnOk;
        private Controles.ControlesPersonalizados.ImagenBoton.ImageButton _iBtnError;
        private Timer _tmMensaje;

        public bool RefrescarCambios { get; set; }

        protected FrmBase()
            : this(FabricaContenedorIoC.Instancia.ContenedorActual)
        {
            InitializeComponent();
        }

        protected FrmBase(IContenedorIoC contenedor)
        {
            ContenedorIoC = contenedor;
        }

        public override AutoValidate AutoValidate
        {
            get
            {
                return AutoValidate.EnableAllowFocusChange;
            }
            set
            {
                base.AutoValidate = value;
            }
        }

        public override Color BackColor
        {
            get { return Color.FromArgb(247, 247, 248); }
            set
            {
                base.BackColor = value;
            }
        }

        protected ContextoUsuario ContextoUsuario
        {
            get
            {
                return ContextoUsuarioManager.Instancia.ContextoUsuario;
            }
        }

        protected ContextoHogar ContextoHogar
        {
            get
            {
                return ContextoHogarManager.Instancia.ContextoHogar;
            }
        }

        protected abstract string Titulo { get; }

        protected T AbrirFormularioModal<T>(T frm, FormClosedEventHandler frmCerrado = null, Action<T> action = null) where T : Form
        {
            frm = ContenedorIoC.Resolver<T>();
            if (action != null) action(frm);
            if (frmCerrado != null)
                frm.FormClosed += frmCerrado;
            frm.ShowDialog();
            return frm;
        }

        protected T AbrirOActivarFormulario<T>(T frm, FormClosedEventHandler frmCerrado = null, Form frmPadre = null, Action<T> action = null) where T : Form
        {
            if (frm == null)
            {
                frm = ContenedorIoC.Resolver<T>();
                frm.MdiParent = frmPadre ?? this;
                if (action != null) action(frm);
                if (frmCerrado != null)
                    frm.FormClosed += frmCerrado;
                frm.Show();
            }
            else
            {
                if (frm.IsDisposed)
                {
                    frm = ContenedorIoC.Resolver<T>();
                    frm.MdiParent = frmPadre ?? this;
                    if (action != null) action(frm);
                    if (frmCerrado != null)
                        frm.FormClosed += frmCerrado;
                    frm.Show();
                }
                else
                {
                    frm.Activate();
                }
            }
            return frm;
        }

        protected bool ChkSeleccionado(Control contenedor, Control control, ErrorProvider ep, string mensaje)
        {
            var seleccionado = contenedor.Controls.OfType<CheckBox>().Any(rb => rb.Checked);
            if (!seleccionado)
            {
                ep.SetError(control, mensaje);
                return false;
            }
            ep.Clear();
            return true;
        }

        //protected void currency_KeyPress(object sender, KeyPressEventArgs e)
        //{
        //    var ch = e.KeyChar;
        //    var txt = sender as TextBox;

        //    if (ch == 44 && txt.Text.IndexOf(',') != -1)
        //    {
        //        e.Handled = true;
        //        return;
        //    }

        //    if (!Char.IsDigit(ch) && ch != 8 && ch != 44)
        //    {
        //        e.Handled = true;
        //    }
        //}

        protected virtual void HabilitarControl(Control control, bool habilitado = true)
        {
            foreach (var ctrl in control.Controls)
            {
                if (ctrl is DateTimePicker) { (ctrl as DateTimePicker).Enabled = habilitado; continue; }
                if (ctrl is DataGridView)
                {
                    var c = (DataGridView)ctrl;
                    c.ReadOnly = !habilitado;
                    c.Enabled = habilitado;
                    continue;
                }
                if (ctrl is RichTextBox)
                {
                    var c = (RichTextBox)ctrl;
                    c.ReadOnly = !habilitado;
                    c.Enabled = habilitado;
                    continue;
                }
                if (ctrl is Button)
                {
                    var c = (Button)ctrl;
                    c.Visible = habilitado;
                    c.Enabled = habilitado;
                    continue;
                }
                if (ctrl is TextBox)
                {
                    var c = (TextBox)ctrl;
                    c.ReadOnly = !habilitado;
                    c.Enabled = true;
                    continue;
                }
                if (ctrl is ComboBox) { (ctrl as ComboBox).Enabled = habilitado; continue; }
                if (ctrl is MaskedTextBox)
                {
                    var c = (MaskedTextBox)ctrl;
                    c.ReadOnly = !habilitado;
                    c.Enabled = habilitado;
                    continue;
                }
                if (ctrl is ListBox) { (ctrl as ListBox).Enabled = habilitado; continue; }
                if (ctrl is Panel) { (ctrl as Panel).Enabled = habilitado; continue; }
                if (ctrl is GroupBox) HabilitarControl(ctrl as GroupBox, habilitado);
            }
        }

        protected virtual void LimpiarControl(Control control)
        {
            foreach (var ctrl in control.Controls)
            {
                if (ctrl is TextBox) (ctrl as TextBox).Text = "";
                else if (ctrl is ComboBox) (ctrl as ComboBox).SelectedIndex = 0;
                else if (ctrl is CheckBox) (ctrl as CheckBox).Checked = false;
                else if (ctrl is RadioButton) (ctrl as RadioButton).Checked = false;
                else if (ctrl is DateTimePicker) (ctrl as DateTimePicker).Value = DateTime.Now.Date;
                else if (ctrl is RichTextBox) (ctrl as RichTextBox).Text = "";
                else if (ctrl is Panel) LimpiarControl((ctrl as Panel));
            }
        }

        protected void maskTextBox_Leave(object sender, EventArgs e)
        {
            var txt = (MaskedTextBox)sender;

            if (txt.MaskFull) return;

            var newText = txt.Text.Aggregate("", (current, t) => current + (t == ' ' ? '0' : t));
            for (var i = 0; i < 5 - txt.Text.Length; i++)
            {
                newText += '0';
            }
            txt.Text = newText;
        }

        protected void OcultarMensajeError()
        {
            _pnlMensaje.Visible = false;
        }

        //protected void MostrarMensajeError(string error)
        //{
        //    _iBtnOk.Visible = false;
        //    _pnlMensaje.Visible = false;
        //    _pnlMensaje.BackColor = _colorPanelError;
        //    _lblMensaje.ForeColor = Color.Red;
        //    _lblMensaje.Text = error;
        //    _lblMensaje.Left = (Width - _lblMensaje.Width) / 2;
        //    _iBtnError.Left = _lblMensaje.Left - (_iBtnError.Width + 10);
        //    _iBtnError.Visible = true;
        //    _pnlMensaje.Visible = true;
        //    //_animador.WaitAllAnimations();
        //    //_animador.Show(_pnlMensaje, false, Animation.HorizBlind);
        //}

        protected void MostrarMensajeError(string error)
        {
            MessageBox.Show(error, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        //protected void MostrarMensajeExito(string mensaje = "")
        //{
        //    //_tmMensaje.Stop();
        //    _pnlMensaje.Visible = false;
        //    _iBtnError.Visible = false;
        //    _pnlMensaje.BackColor = _colorPanelExito;
        //    _lblMensaje.ForeColor = Color.Black;
        //    _lblMensaje.Text = Resources.Base_Guardo_ConExito;
        //    if (!string.IsNullOrEmpty(mensaje))
        //        _lblMensaje.Text = mensaje;
        //    _lblMensaje.Left = (Width - _lblMensaje.Width) / 2;
        //    _iBtnOk.Left = _lblMensaje.Left - (_iBtnOk.Width + 10);
        //    _iBtnOk.Visible = true;
        //    _pnlMensaje.Visible = true;
        //    //_animador.WaitAllAnimations();
        //    //_tmMensaje.Enabled = true;
        //    //_animador.Show(_pnlMensaje, false, Animation.HorizBlind);
        //}

        protected void MostrarMensajeExito(string mensaje = "")
        {
            _lblMensaje.Text = Resources.Base_Guardo_ConExito;
            if (!string.IsNullOrEmpty(mensaje))
                _lblMensaje.Text = mensaje;
            MessageBox.Show(_lblMensaje.Text, "", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        protected bool RbSeleccionado(Control contenedor, Control control, ErrorProvider ep, string mensaje)
        {
            var seleccionado = contenedor.Controls.OfType<RadioButton>().Any(rb => rb.Checked);
            if (!seleccionado)
            {
                ep.SetError(control, mensaje);
                return false;
            }
            ep.Clear();
            return true;
        }

        protected void textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            var ch = e.KeyChar;

            if (!Char.IsDigit(ch) && ch != 8)
            {
                e.Handled = true;
            }
        }

        private void FrmBase_Load(object sender, EventArgs e)
        {
            _pnlSeparador.Width = Width;
            _lblTitulo.Text = Titulo;
            _pnlSeparador.Visible = !string.IsNullOrEmpty(Titulo);
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            GDM.Hogar.Controles.Animacion.Animation animation1 = new GDM.Hogar.Controles.Animacion.Animation();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmBase));
            this._lblMensaje = new System.Windows.Forms.Label();
            this._pnlMensaje = new System.Windows.Forms.Panel();
            this._iBtnError = new GDM.Hogar.Controles.ControlesPersonalizados.ImagenBoton.ImageButton();
            this._iBtnOk = new GDM.Hogar.Controles.ControlesPersonalizados.ImagenBoton.ImageButton();
            this._animador = new GDM.Hogar.Controles.Animacion.Animator(this.components);
            this._pnlSeparador = new System.Windows.Forms.Panel();
            this._lblTitulo = new System.Windows.Forms.Label();
            this._tmMensaje = new System.Windows.Forms.Timer(this.components);
            this._pnlMensaje.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this._iBtnError)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this._iBtnOk)).BeginInit();
            this.SuspendLayout();
            // 
            // _lblMensaje
            // 
            this._lblMensaje.AutoSize = true;
            this._animador.SetDecoration(this._lblMensaje, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this._lblMensaje.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this._lblMensaje.ForeColor = System.Drawing.Color.Black;
            this._lblMensaje.Location = new System.Drawing.Point(99, 5);
            this._lblMensaje.Name = "_lblMensaje";
            this._lblMensaje.Size = new System.Drawing.Size(201, 17);
            this._lblMensaje.TabIndex = 0;
            this._lblMensaje.Text = "Los datos se guardaron con exito";
            this._lblMensaje.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // _pnlMensaje
            // 
            this._pnlMensaje.BackColor = System.Drawing.SystemColors.Control;
            this._pnlMensaje.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
            this._pnlMensaje.Controls.Add(this._iBtnError);
            this._pnlMensaje.Controls.Add(this._iBtnOk);
            this._pnlMensaje.Controls.Add(this._lblMensaje);
            this._animador.SetDecoration(this._pnlMensaje, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this._pnlMensaje.Dock = System.Windows.Forms.DockStyle.Top;
            this._pnlMensaje.ForeColor = System.Drawing.Color.Black;
            this._pnlMensaje.Location = new System.Drawing.Point(0, 0);
            this._pnlMensaje.Name = "_pnlMensaje";
            this._pnlMensaje.Size = new System.Drawing.Size(684, 28);
            this._pnlMensaje.TabIndex = 17;
            this._pnlMensaje.Visible = false;
            // 
            // _iBtnError
            // 
            this._animador.SetDecoration(this._iBtnError, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this._iBtnError.DialogResult = System.Windows.Forms.DialogResult.None;
            this._iBtnError.DownImage = null;
            this._iBtnError.HoverImage = null;
            this._iBtnError.Location = new System.Drawing.Point(331, 3);
            this._iBtnError.Name = "_iBtnError";
            this._iBtnError.NormalImage = global::GDM.Hogar.Aplicacion.Properties.Resources.status_error;
            this._iBtnError.Size = new System.Drawing.Size(22, 22);
            this._iBtnError.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this._iBtnError.TabIndex = 2;
            this._iBtnError.TabStop = false;
            this._iBtnError.Visible = false;
            // 
            // _iBtnOk
            // 
            this._animador.SetDecoration(this._iBtnOk, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this._iBtnOk.DialogResult = System.Windows.Forms.DialogResult.None;
            this._iBtnOk.DownImage = null;
            this._iBtnOk.HoverImage = null;
            this._iBtnOk.Location = new System.Drawing.Point(73, 3);
            this._iBtnOk.Name = "_iBtnOk";
            this._iBtnOk.NormalImage = global::GDM.Hogar.Aplicacion.Properties.Resources.success;
            this._iBtnOk.Size = new System.Drawing.Size(22, 22);
            this._iBtnOk.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this._iBtnOk.TabIndex = 1;
            this._iBtnOk.TabStop = false;
            this._iBtnOk.Visible = false;
            // 
            // _animador
            // 
            this._animador.AnimationType = GDM.Hogar.Controles.Animacion.AnimationType.VertSlide;
            this._animador.Cursor = null;
            animation1.AnimateOnlyDifferences = true;
            animation1.BlindCoeff = ((System.Drawing.PointF)(resources.GetObject("animation1.BlindCoeff")));
            animation1.LeafCoeff = 0F;
            animation1.MaxTime = 1F;
            animation1.MinTime = 0F;
            animation1.MosaicCoeff = ((System.Drawing.PointF)(resources.GetObject("animation1.MosaicCoeff")));
            animation1.MosaicShift = ((System.Drawing.PointF)(resources.GetObject("animation1.MosaicShift")));
            animation1.MosaicSize = 0;
            animation1.Padding = new System.Windows.Forms.Padding(0);
            animation1.RotateCoeff = 0F;
            animation1.RotateLimit = 0F;
            animation1.ScaleCoeff = ((System.Drawing.PointF)(resources.GetObject("animation1.ScaleCoeff")));
            animation1.SlideCoeff = ((System.Drawing.PointF)(resources.GetObject("animation1.SlideCoeff")));
            animation1.TimeCoeff = 0F;
            animation1.TransparencyCoeff = 0F;
            this._animador.DefaultAnimation = animation1;
            // 
            // _pnlSeparador
            // 
            this._pnlSeparador.BackColor = System.Drawing.Color.Silver;
            this._animador.SetDecoration(this._pnlSeparador, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this._pnlSeparador.Location = new System.Drawing.Point(12, 49);
            this._pnlSeparador.Name = "_pnlSeparador";
            this._pnlSeparador.Size = new System.Drawing.Size(430, 1);
            this._pnlSeparador.TabIndex = 36;
            // 
            // _lblTitulo
            // 
            this._lblTitulo.AutoSize = true;
            this._animador.SetDecoration(this._lblTitulo, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this._lblTitulo.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this._lblTitulo.ForeColor = System.Drawing.Color.DarkSlateGray;
            this._lblTitulo.Location = new System.Drawing.Point(12, 31);
            this._lblTitulo.Name = "_lblTitulo";
            this._lblTitulo.Size = new System.Drawing.Size(47, 16);
            this._lblTitulo.TabIndex = 35;
            this._lblTitulo.Text = "Titulo";
            // 
            // _tmMensaje
            // 
            //this._tmMensaje.Tick += new System.EventHandler(this.tmMensaje_Tick);
            // 
            // FrmBase
            // 
            this.ClientSize = new System.Drawing.Size(684, 64);
            this.Controls.Add(this._pnlSeparador);
            this.Controls.Add(this._lblTitulo);
            this.Controls.Add(this._pnlMensaje);
            this._animador.SetDecoration(this, GDM.Hogar.Controles.Animacion.DecorationType.None);
            this.Name = "FrmBase";
            this.Load += new System.EventHandler(this.FrmBase_Load);
            this._pnlMensaje.ResumeLayout(false);
            this._pnlMensaje.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this._iBtnError)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this._iBtnOk)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void tmMensaje_Tick(object sender, EventArgs e)
        {
            _tmMensaje.Enabled = false;
            _animador.WaitAllAnimations();
            _animador.Hide(_pnlMensaje, false, Animation.HorizBlind);
        }

        protected bool GrillaValida(DataGridView dgv)
        {
            return dgv.Rows.Cast<DataGridViewRow>().All(row => string.IsNullOrEmpty(row.ErrorText));
        }
    }
}